#include "command.h"

#define BUFFERSIZE 4096

//私有通信协议， 因为TCP通信是字节流，没有边界，
//通过私有协议，能让发送接收方遵守确定的边界，接收数据
//定义一个小火车的私有协议
typedef struct train_t {
    int length;
    char buf[BUFFERSIZE];
} train_t;


int sendn(int fd, const void* str, int len);

//上传文件到服务器，需要一个用于通信的文件描述符。
//检查本地是否有这样一个文件
//



//接收客户端上传的文件
int recv_file(int fd)
{
    int ret = -1;
    //1、接收文件名, 发送过来的命令，已经知道文件名了，还有必要接收文件名吗
    int len;
    ret = recv(fd, &len, 4, 0);  //int len来接收的文件名长度
    ERROR_CHECK_G(ret, -1, "recv");

    char recv_buf[BUFFERSIZE] = {0};
    ret = recv(fd, recv_buf, len, 0);
    printf(">>2 recv filename: %s\n", recv_buf);

    //2、在服务器创建文件
    int fd_file = open(recv_buf, O_WRONLY | O_TRUNC | O_CREAT, 0666);
    ERROR_CHECK_G(ret, -1, "recv");


    //TCP是一个字节流协议！----注意
    //3、接收文件大小，，接收到的是字符串格式数据
    off_t file_size;
    ret = recv(fd, &len, 4, MSG_WAITALL);
    ERROR_CHECK_G(ret, -1, "recv");
    ret = recv(fd, &file_size, sizeof(file_size), MSG_WAITALL);
    ERROR_CHECK_G(ret, -1, "recv");
    printf(">> file length: %ld\n", file_size);

    off_t slice = file_size / 100;
    //4、接收文件内容
    off_t download_size = 0;
    off_t last_size = 0;
    int percent = 0;  //定义了while外
    while (download_size < file_size) {
        ret = recv(fd, &len, 4, MSG_WAITALL);  //小火车文件长度
        ERROR_CHECK_G(ret, -1, "recv");
        if (0 == ret) {  //最后一次没有信息，发送过来的长度是零
            puts("file has recv all data");
            break;
        }

        memset(recv_buf, 0, BUFFERSIZE);
        ret = recv(fd, recv_buf, len, MSG_WAITALL);  //小火车文件内容
        ERROR_CHECK_G(ret, -1, "recv");

        download_size += ret;

        //打印下载百分比的代码，用整数实现
        if (download_size - last_size > slice ) {
            percent++;
            printf(">> download percent: %d\n", percent);
            last_size += slice;  //这样是正好的百分比
        }

        //5、写入本地
        ret = write(fd_file, recv_buf, ret);
        ERROR_CHECK_G(ret, -1, "write");

    }
    //4、关闭打开文件的文件描述符
    close(fd_file);

    return 0;
}

int sendn(int fd, const void* str, int len)
{
    char*  train= (char* )str;
    int left = len;
    int ret = -1;

    while (left > 0) {
        ret = send(fd, train, left, 0);
        if (-1 == ret) {
            perror("send");
            break;
        }
        else {
            train += ret;
            left -= ret;
        }
    }
    return len - left;
}
